using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace Acms.WebControls
{
    public class CheckedRequiredValidator : BaseValidator
    {
        private string[] controlsToValidate;
        [TypeConverter(typeof(StringArrayConverter))]
        public string[] ControlsToValidate
        {
            get { return controlsToValidate; }
            set { controlsToValidate = value; }
        }

        protected override bool ControlPropertiesValid()
        {
            if (controlsToValidate == null || controlsToValidate.Length == 0)
            {
                throw new HttpException("ControlsToValidate property not set");
            }

            string groupName = null;
            bool? isCheckBox = null;
            foreach (string id in ControlsToValidate)
            {
                Control tmp = this.NamingContainer.FindControl(id);
                //check control is radio button of checkbox
                if (tmp == null)
                {
                    throw new HttpException(string.Format("Control '{0}' could not be found", id));
                }
                else if(!(tmp is CheckBox || tmp is RadioButton))
                {
                    throw new HttpException(string.Format("Control '{0}' is a '{1}' and can only validate CheckBox or item"));
                }
                //check not mixing controls
                if (isCheckBox == null)
                {
                    isCheckBox = tmp is CheckBox;
                }
                else if(isCheckBox.Value && !(tmp is CheckBox) || !isCheckBox.Value && (tmp is CheckBox))
                {
                    throw new HttpException(string.Format("Already validating '{0}' cannot validate '{1}' as well", isCheckBox.Value ? "CheckBoxs" : "RadioButtons", tmp.GetType().ToString()));
                }
                //if radio buttons check group name
                if (tmp is RadioButton)
                {
                    if (groupName == null)
                    {
                        groupName = ((RadioButton)tmp).GroupName;
                    }
                    else if (groupName != ((RadioButton)tmp).GroupName)
                    {
                        throw new HttpException(string.Format("Radio Button GroupName '{0}' does not match original GroupName '{1}'.", ((RadioButton)tmp).GroupName, groupName));
                    }
                }
            }
            return true;
        }

        protected override bool EvaluateIsValid()
        {
            foreach (string id in ControlsToValidate)
            {
                Control tmp = NamingContainer.FindControl(id);
                if (tmp is RadioButton)
                {
                    if (((RadioButton)tmp).Checked)
                        return true;
                }
                else if (tmp is CheckBox)
                {
                    if (((CheckBox)tmp).Checked)
                        return true;
                }
            }
            return false;
        }

        protected override void OnPreRender(EventArgs e)
        {
            string javascript = @"
                function evalCheckedRequiredValidator(e)
                {
                    var arr = e.controlsToValidate.split(""|"");
                    for(var i = 0; i < arr.length; i++)
                    {
                        if(document.getElementById(arr[i]).checked)
                        {
                            return true;
                        }

                    }
                    return false;
                }
            ";
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "evalCheckedRequiredValidator", javascript, true);
            base.OnPreRender(e);
        }

        protected override void RegisterValidatorDeclaration()
        {
            base.RegisterValidatorDeclaration();
            StringBuilder tmp = new StringBuilder();
            string spacer = "";
            foreach(string id in ControlsToValidate)
            {
                tmp.Append(spacer);
                tmp.Append(this.NamingContainer.FindControl(id).ClientID);
                spacer = "|";
            }
            Page.ClientScript.RegisterExpandoAttribute(this.ClientID, "controlsToValidate", tmp.ToString());
            Page.ClientScript.RegisterExpandoAttribute(this.ClientID, "evaluationfunction", "evalCheckedRequiredValidator");
        }
    }
}
